﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FE.Common;
using fe.pdf.convert.jobs.webapp.Helper;
using FE.Service.Contract;
using FE.Service.Repository.SqlSugar;
using FE.Shared;
using FE.Shared.Entity;
using FE.Shared.Enum;
using Microsoft.Extensions.Logging;

namespace fe.pdf.convert.jobs.webapp.Jobs
{
    public class TaskService : ITaskService
    {
        private readonly IAppService _appService;

        private readonly ILogger<TaskService> _logger;
        private readonly IMySqlDbContext _dbContext;

        

        public TaskService(IAppService appService
            , ILogger<TaskService> logger
            , IMySqlDbContext dbContext)
        {
            _appService = appService;
            _logger = logger;
            _dbContext = dbContext;
        }

        private bool ValidateAppSettings(AppSettings settings)
        {
            if (settings == null)
            {
                return false;
            }

            if (settings.ServerMySqlSettings == null)
            {
                return false;
            }

            if (settings.ServerPathSettings == null)
            {
                return false;
            }

            if (settings.ServerPathSettings.FileMode == null || settings.ServerPathSettings.FileMode <= 0)
            {
                return false;
            }

            return true;
        }

        public void Run()
        {
            //开始运行日志
            _logger.LogInformation($"jobs开始运行于[{DateTime.Now.ToShortDateString()}]");
            

            // 1 get data
            // 2 根据获取的数据循环处理转换
            var settings = _appService.ReadAppSettings();

            //验证必须的三要素是否具备,如果不具备则跳出
            var valid = ValidateAppSettings(settings);

            if (!valid)
            {
                //_logger.LogError("配置文件设置不正确,请重新修改!");
                return;
            }

            //从数据库获取所有的附件列表
            var attachmentList = _dbContext.GetAttachmentList();
            if (attachmentList?.Count() > 0)
            {
                //todo 如果数据特别多,是否考虑分1000条执行一次?

                if (settings.ServerPathSettings.FileMode == 1)
                {
                    //文件夹模式
                    RunJobAsFolderMode(settings, attachmentList.ToList());
                }
                else
                {
                    //sftp模式
                    RunJobAsSftpMode(settings, attachmentList.ToList());
                }
            }
        }

        private void RunJobAsFolderMode(AppSettings settings, List<Sys_Attachment> attachmentList)
        {
            //从服务器获取已经产生的文件, 比对是否文件已经产生, 即已经产生的PDF无需处理
            var fileList = FileHelper.GetFileInfos(settings.ServerPathSettings.PdfGeneratedServerPath);

            foreach (var attachment in attachmentList)
            {
                //1 保存名称
                //attachment.SA02
                //todo 如果是sftp,处理
                var file = fileList.ToList().Where(f => f.FullName.Contains(attachment.SA02));

                if (file?.Count() > 0)
                {
                    //2 已经存在,说明PDF已经生成了,不需要处理
                    _dbContext.UpdateAttachmentStatus(attachment.SA00, AttachmentStatus.NoNeedGenerate,
                        "PDF已生成,不需要重复生成!");
                }
                else
                {
                    try
                    {
                        //todo 如果这里是linux, 必须使用sftp
                        //组装文件位置
                        //源文件位置存放在db中, 但这里需要设置访问权限
                        string sourcePath = attachment.SA04 + "\\" + attachment.SA02;
                        //本地下载目录,需要将源文件下载到本地 todo 验证
                        string targetPath = settings.ServerPathSettings.FileAttachmentRootPath + "\\" + attachment.SA02;
                        //pdf生成的目录 ,最后需要上传到这里的
                        string generatedPdfPath = settings.ServerPathSettings.PdfGeneratedServerPath + "\\" + attachment.SA02 + ".pdf";

                        //标记为运行状态
                        _dbContext.UpdateAttachmentStatus(attachment.SA00, AttachmentStatus.Running,
                            $"pdf转换开始,转换时间为:{DateTime.Now.ToShortTimeString()}");

                        //3.1 先保存文件到本地
                        FileHelper.CopyFile(sourcePath, targetPath);
                        //3.2 开始转换
                        PdfConverter.Convert(targetPath, targetPath + ".PDF");
                        //3.3 转换如果成功,标记数据库
                        if (File.Exists(targetPath + ".PDF"))
                        {
                            //3.4 将生成的PDF返回到服务器
                            FileHelper.CopyFile(targetPath + ".PDF", generatedPdfPath);

                            //更新表记录
                            _dbContext.UpdateAttachmentStatus(attachment.SA00, AttachmentStatus.Success,
                                $"pdf转换成功,转换时间为:{DateTime.Now.ToShortTimeString()}");
                        }
                        else
                        {
                            _dbContext.UpdateAttachmentStatus(attachment.SA00, AttachmentStatus.Failed, "文件生成失败.");
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        //throw;
                        //_logger.LogError(e.Message);
                        _dbContext.UpdateAttachmentStatus(attachment.SA00, AttachmentStatus.Failed,
                            $"转换时异常,异常日志:[{e.Message}]");
                    }
                }
                //}
            }
        }

        private void RunJobAsSftpMode(AppSettings settings, List<Sys_Attachment> attachmentList)
        {
        }

        private FileInfo[] GetGeneratedPdfList(AppSettings settings)
        {
            if (settings == null || settings.ServerPathSettings == null || settings.ServerPathSettings?.FileMode <= 0)
            {
                return new FileInfo[] { };
            }
            else
            {
                if (settings.ServerPathSettings.FileMode == 1)
                {
                    return FileHelper.GetFileInfos(settings.ServerPathSettings.PdfGeneratedServerPath);
                }
                else
                {
                    //SftpHelper.Download();
                }
            }

            return new FileInfo[] { };
        }

        
    }
}
